浏览器兼容性问题
# 浏览器兼容性问题
[TOC]
IE8/9/10/11Edge、Chrome、Firefox
兼容性查询:https://caniuse.com/ (opens new window)
判断浏览器:https://github.com/mumuy/browser/blob/master/Browser.js(浏览器检测 亲测有效)
# 一、CSS样式
# 1.1 浏览器样式差异
# 1.1.1 reset.css
重置样式,抛弃默认样式。
# 1.1.2 normalize.css
让浏览器的标签都跟标准规定的默认样式一致,各浏览器上的标签默认样式基本统一。
# 1.2 浏览器兼容前缀
在CSS3还没有成为真正的标准时,浏览器厂商就开始支持这些属性的使用了。CSS3样式语法还存在波动时,浏览器厂商提供了针对浏览器的前缀,直到现在还是有部分的属性需要加上浏览器前缀。在开发过程中我们一般通过IDE开发插件、css 预处理器以及前端自动化构建工程帮我们处理。
vue-cli会自动补充前缀。
内核 | 主浏览器 | 前缀 |
---|---|---|
Trident三叉戟 /'traidnt/ | IE | -ms- |
EdgeHTML | Edge | |
Gecko壁虎 /'gɛko/ | Firefox | -moz- |
Presto很快 /'prestou/ | Opera | -o- |
Blink(28~)/ Webkit(Chrome 27) | Chrome | -webkit- |
Webkit装备 | Safari | -webkit- |
# 1.2.1 动画
- transform
transform:rotate(4deg); //统一标识语句
-webkit-transform:rotate(4deg); //Chrome、Safari
-moz--transform:rotate(4deg); //Firefox
-o-transform:rotate(4deg); //Opera
-ms-transform:rotate(4deg); //IE
2
3
4
5
- @keyframes
- transition
- animation
# 1.2.2 透明度
opacity: 0.5;
filter: alpha(opacity = 50); // 兼容IE8
2
# 1.2.3 渐变
- linear-gradient
- radial-gradient
# 1.2.4 边框
- border-radius:需兼容IE8、Opera
- box-shadow:需兼容IE8、Opera
# 1.3 兼容模式
<!--什么版本IE就用什么版本的标准模式:-->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--使用以下代码强制IE使用Chrome Frame:-->
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<!--最佳的兼容模式方案,结合考虑以上两种:-->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
2
3
4
5
6
7
8
# 二、JS兼容
# 2.1 事件
方法 | 标准 | IE |
---|---|---|
监听事件 | element.addEventListener() 有捕获无on | element.attachEvent() 无捕获有on |
事件对象 | event | window.event |
目标元素 | event.target | event.srcElement |
取消默认事件 | event.preventDefault() IE8以上 | event.returnValue = false |
解绑事件 | element.removeEventListener() | element.detachEvent() |
阻止冒泡 | event.stopPropagation() | event.cancelBubble = true IE11以下 |
- 取消默认事件
//无兼容问题(但不能用于节点直接onclick绑定函数)
return false;
2
- EventUtil
var EventUtil = {
addHandler: function (element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
}
},
getEvent: function (event) {
return event || window.event;
},
getTarget: function (event) {
return event.target || event.srcElement;
},
preventDefault: function (event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
removeHandler: function (element, type, handler) {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.detachEvent) {
element.detachEvent("on" + type, handler);
}
},
stopPropagation: function (event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
btn.onclick = (event) => {
// 这一步要先写
let event = EventUtil.getEvent(event);
let target = EventUtil.getTarget(event);
};
2
3
4
5
# 2.2 浏览器窗口
# 2.2.1 滚动条滚动距离
//标准浏览器
document.documentElement.scrollTop[scrollLef]
//谷歌浏览器
document.body.scrollTop[scrollLeft]
//兼容不同的浏览器
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
2
3
4
5
6
# 2.2.2 窗口大小
document.documentElement.clientWidth || document.body.clientHeight
# 2.3 样式
# 2.3.1 浮动
// IE
oDiv.style.styleFloat = 'left';
// 非IE
oDiv.style.cssFloat = 'left';
// 兼容模式
oDiv.style.cssText = 'float: left;';
2
3
4
5
6
# 2.3.2 获取样式
// 兼容IE8,IE独有
if(obj.currentStyle) {
return obj.currentStyle[attr];
} else {
// 兼容火狐谷歌,IE9以上
// 不能通过document对象调用,只能通过一个元素节点对象调用它
return getComputedStyle(obj)[attr];
}
2
3
4
5
6
7
8
# 2.4 滚动事件
兼容所有HTML5浏览器:
window.onwheel = (e) => { console.log(e.deltaY); } // 上:-100;下:100
1
2
3
4
5
# 2.4.1 onmousewheel/DOMMouseScroll
ie/chrome : onmousewheel
firefox : DOMMouseScroll
必须用addEventListener
oDiv.onmousewheel = fn;
//因为ie没有addEventListener这个属性,所以要做判断
oDiv.addEventListener && oDiv.addEventListener('DOMMouseScroll', fn, false);
2
3
# 2.4.2 wheelDelta/detail
ie/chrome : event.wheelDelta
上:120;下-120
firefox : event.detail
上:-3;下:3
//兼容处理
var b = true;
if (ev.wheelDelta) {
b = ev.wheelDelta > 0 ? true : false;
} else {
b = ev.detail < 0 ? true : false;
}
2
3
4
5
6
7
# 三、jQuery消除主流浏览器差异
等看源码再议
# 四、IE8支持HTML5标签
- 通过
document.createElement()
创建html5新标签。
(function() {
// 页面头部
var a = ['section', 'article', 'nav', 'header', 'footer' /* 其他HTML5元素 */];
for (var i = 0, j = a.length; i < j; i++) {
document.createElement(a[i]);
}
})();
2
3
4
5
6
7
# 五、通信
# 5.1 XMLHttpRequest
# 5.1.1 兼容性
- IE8/IE9、Opera Mini 完全不支持
xhr
对象 - IE10/IE11部分支持,不支持
xhr.responseType
为json
- 部分浏览器不支持设置请求超时,即无法使用
xhr.timeout
- 部分浏览器不支持
xhr.responseType
为blob
# 5.2 CORS
IE8、IE9不兼容,其余浏览器都支持。
解决方案:代理devServer.proxy (opens new window)
webpack 的
devServer.proxy
的功能是由 http-proxy-middleware (opens new window) 项目来实现的实现原理是将目标位置的请求代理为前端服务本地的请求,既然是代理成为本地的请求,就不存在跨域的问题,axios 就会用回
XMLHttpRequest
对象进行数据请求,一切都恢复正常了,header、cookies、content-type、authentication 等内容都被正确传递到服务端。